﻿using STHPMS1.Common.C_Entity;
using STHPMS1.Common.C_Enum;
using STHPMS1.ICore.I_DAL;
using STHPMS1.ICore.I_Entity.Stmpms1;
using STHPMS1.ICore.I_Serv;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using STHPMS1.Common.C_Extension;
using STHPMS1.Common.C_Entity.Stmpms1;

namespace STHPMS1.BLL.B_Serv
{
    public class DeflectionCalculateService : IDeflectionCalculateService
    {
        private List<Dm_Default_Traffic_Coeff> _carDefList;

        public DeflectionCalculateService()
        {
            _carDefList = new List<Dm_Default_Traffic_Coeff>();
        }

        public void CalacDeflection(ISthpms1Dao dao)
        {
            _carDefList = dao.Select<Dm_Default_Traffic_Coeff>();
            if (_carDefList.Count == 0) throw new Exception("交通量轴载默认值数据为空!");
            foreach (Dm_Default_Traffic_Coeff traffic in _carDefList)
            {
                traffic.Front_AxesCoeff = CalacAxes(traffic.Front_Axes);
                traffic.C_Front_AxesCoeff = CalacAxes(traffic.C_Front_Axes);
                traffic.Rear_AxesCoeff = CalacAxes (traffic.Rear_Axes);
                traffic.C_Rrear_AxesCoeff = CalacAxes(traffic.C_Rrear_Axes);

                traffic.Front_WheelsCoeff = CalacWheels(traffic.Front_Wheels);
                traffic.C_Front_WheelsCoeff = CalacWheels(traffic.C_Front_Wheels);
                traffic.Rear_WheelsCoeff =  CalacWheels(traffic.Rear_Wheels);
                traffic.C_Rrear_WheelsCoeff = CalacWheels(traffic.C_Rrear_Wheel);
            }
        }

        /// <summary>
        /// 计算设计弯沉值 
        /// </summary>
        /// <param name="traffic"></param>
        /// <param name="front_axle"></param>
        /// <param name="c_front_axle"></param>
        /// <param name="rear_axle"></param>
        /// <param name="c_rear_axle"></param>
        /// <returns></returns>
        private double CalacDeflection(Dm_Default_Traffic_Coeff traffic,double? front_axle,double? c_front_axle,double? rear_axle,double ?c_rear_axle)
        {
            return CalaN(traffic.Front_AxesCoeff, traffic.Front_WheelsCoeff,  front_axle) +
                        CalaN(traffic.C_Front_AxesCoeff, traffic.C_Front_WheelsCoeff,  c_front_axle) +
                        CalaN(traffic.Rear_AxesCoeff, traffic.Rear_WheelsCoeff,  rear_axle) +
                        CalaN(traffic.C_Rrear_AxesCoeff, traffic.C_Rrear_WheelsCoeff, c_rear_axle);
        }

        private double? CalacAxes(double? axes)
        {
            if (axes == null) 
                return null;
            else
                return 1 + 1.2 * (axes - 1);
        }

        private double? CalacWheels(double? wheels)
        {
            if (wheels == null) return null;
            else if (wheels == 1) return 6.4;
            else if (wheels == 2) return 1;
            else if (wheels == 4) return 0.38;
            return 0;
        }

        private double CalaN(double? axescoeff,double? wheelcoeff,double? axle)
        {
            if (axescoeff == null || wheelcoeff == null || axle == null)
                return 0;
            else
                return axescoeff.ToD() * wheelcoeff.ToD()* Math.Pow((axle.ToD()/ 100), 4.35d);
        }

        public double CalcDailyEASL(IS_Trfvolsurvey trf, IS_Axleload axle)
        {
            double value=0;
            if (_carDefList==null || _carDefList.Count == 0) throw new Exception("交通量轴载默认值数据为空!");

            Dictionary<CarEnum, double> carList = new Dictionary<CarEnum, double>();
            Dictionary<CarEnum, Dm_Default_Traffic_Coeff> weightList = new Dictionary<CarEnum, Dm_Default_Traffic_Coeff>();

            foreach (var item in Enum.GetValues(typeof(CarEnum)).Cast<CarEnum>())
            {
                carList.Add(item, 0);
            }

            if (trf != null)
            {
                if (trf.Truck_S != null || trf.Truck_S != 0)//载重汽车-小型（辆）
                {
                    carList[CarEnum.C1000] += trf.Truck_S.ToI();
                }
                if (trf.Truck_M != null || trf.Truck_M != 0)//载重汽车-中型（辆）
                {
                    carList[CarEnum.C1001] += trf.Truck_M.ToI();
                }
                if (trf.Truck_L != null || trf.Truck_L != 0)//载重汽车-大型（辆）
                {
                    carList[CarEnum.C1002] += trf.Truck_L.ToI();
                }
                if (trf.Truck_O != null || trf.Truck_O != 0)//载重汽车-特大型（辆）
                {
                    carList[CarEnum.C1003] += trf.Truck_O.ToI();
                }
                if (trf.Car_S != null || trf.Car_S != 0)//客车-小型（辆）
                {
                    carList[CarEnum.C1004] += trf.Car_S.ToI();
                }
                if (trf.Car_L != null || trf.Car_L != 0)//客车-大型（辆）
                {
                    carList[CarEnum.C1005] += trf.Car_L.ToI();
                }
                if (trf.Artveh != null || trf.Artveh != 0)//拖挂车（辆）
                {
                    carList[CarEnum.C1006] += trf.Artveh.ToI();
                }
                if (trf.Contcar != null || trf.Contcar != 0)//集装箱车（辆）
                {
                    carList[CarEnum.C1007] += trf.Contcar.ToI();
                }
                if (trf.Tractor != null || trf.Tractor != 0)//拖拉机（辆）
                {
                    carList[CarEnum.C1008] += trf.Tractor.ToI();
                }
            }

            if (axle != null)
            {
                CarEnum key = (CarEnum)axle.Repreveh_Dictid;
                if (!weightList.ContainsKey(key))
                {
                    weightList.Add(key, new Dm_Default_Traffic_Coeff());
                }
                if (string.IsNullOrEmpty(axle.Ealf_Dictid)) throw new Exception("轴载数据不正确-轴型为空：" + axle.Axleid);
                var length = axle.Ealf_Dictid.Split('+').Length;
                Dm_Default_Traffic_Coeff coeff = weightList[key];
                if (length == 2)
                {
                    coeff.Front_Axle += axle.Eaweight1;
                    coeff.Rear_Axle += axle.Eaweight2;
                }
                else if (length == 3)
                {
                    coeff.Front_Axle += axle.Eaweight1;
                    coeff.C_Front_Axle += axle.Eaweight2;
                    coeff.Rear_Axle += axle.Eaweight3;
                }
                else if (length == 4)
                {
                    coeff.Front_Axle += axle.Eaweight1;
                    coeff.C_Front_Axle += axle.Eaweight2;
                    coeff.C_Rrear_Axle += axle.Eaweight3;
                    coeff.Rear_Axle += axle.Eaweight4;
                }
                else
                {
                    throw new Exception("轴载数据不正确-轴型不存在：" + axle.Axleid);
                }
            }

            foreach (var car in carList)
            {
                var type = _carDefList.Where(p => p.Cartype.Contains(car.Key.GetEnumValue().ToString()));
                var avg = car.Value / type.Count();
                foreach (var traffic in type)
                {
                    Dm_Default_Traffic_Coeff def = traffic;
                    double deflection =0;
                    if(weightList.ContainsKey(car.Key))
                    {
                        def = weightList[car.Key];
                    }
                    deflection = CalacDeflection(traffic, def.Front_Axle, def.C_Front_Axle, def.Rear_Axle, def.C_Rrear_Axle);//弯沉值
                    value += deflection * avg;
                }
            }
            return value/1000000;
        }

        public double CalcAADT(double deflection, double lanecoef, double directcoef)
        {
            return deflection * lanecoef * directcoef * 365;
        }

        public double CalcDesginerEASL(double aadt,  double desgineryear, double growthrate)
        {
            return (Math.Pow((1 + growthrate), desgineryear) - 1) * aadt / growthrate;
        }
    }
}
